﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Text;
using System.Xml;
using System.Xml.XPath;

namespace WFL.Windows.Forms.Theme
{
    public abstract class XmlSkinBase : SkinBase
    {
        public delegate Image GetPreview(string name);

        protected IList<SkinItem> GetListFromXml(string xml, GetPreview getPreview)
        {
            IList<SkinItem> list = null;
            StringReader sr = new StringReader(xml);
            try
            {
                XPathDocument xDoc = new XPathDocument(sr);
                XPathNavigator xNav = xDoc.CreateNavigator();
                XPathNodeIterator xIter = xNav.Select("/skins/skin");
                if (xIter.Count > 0)
                {
                    list = new List<SkinItem>(xIter.Count);
                    while (xIter.MoveNext())
                    {
                        string id = xIter.Current.GetAttribute("id", "");
                        string name = xIter.Current.GetAttribute("name", "");
                        string preview = xIter.Current.GetAttribute("preview", "");
                        SkinItem item = new SkinItem(id, name);
                        if (!string.IsNullOrEmpty(preview)
                            && getPreview != null)
                        {
                            item.Preview = getPreview(preview);
                        }
                        list.Add(item);
                    }
                }
                return list;
            }
            finally
            {
                sr.Close();
            }
        }

        protected void LoadStylesFromXml(string xml)
        {
            StringReader sr = new StringReader(xml);
            try
            {
                XPathDocument xDoc = new XPathDocument(sr);
                XPathNavigator xNav = xDoc.CreateNavigator();
                XPathNodeIterator xIter = xNav.Select("/skin/style");
                if (xIter.Count > 0)
                {
                    Styles = new Dictionary<string, Style>(xIter.Count);
                    while (xIter.MoveNext())
                    {
                        LoadStyleFromXml(xIter.Current);
                    }
                }
            }
            finally
            {
                sr.Close();
            }
        }

        private void LoadStyleFromXml(XPathNavigator xNav)
        {
            string name = xNav.GetAttribute("name", "");
            if (Styles.ContainsKey(name))
            {
                return;
            }
            string inherit = xNav.GetAttribute("inherit", "");
            Dictionary<string, string> properties = null;
            if (!string.IsNullOrEmpty(inherit))
            {
                if (!Styles.ContainsKey(inherit))
                {
                    XPathNavigator xNav1 = xNav.SelectSingleNode("/skin/style[@name='" + inherit + "']");
                    if (xNav1 != null)
                    {
                        LoadStyleFromXml(xNav1);
                    }
                }
                if (Styles.ContainsKey(inherit))
                {
                    Style inheritStyle = Styles[inherit];
                    if (inheritStyle.Properties != null
                        && inheritStyle.Properties.Count > 0)
                    {
                        properties = new Dictionary<string, string>();
                        foreach (KeyValuePair<string, string> pair in inheritStyle.Properties)
                        {
                            properties.Add(pair.Key, pair.Value);
                        }
                    }
                }
            }
            if (xNav.MoveToChild("properties", ""))
            {
                if (xNav.MoveToFirstAttribute())
                {
                    if (properties == null)
                    {
                        properties = new Dictionary<string, string>();
                    }
                    do
                    {
                        string key = xNav.LocalName;
                        string value = xNav.Value;
                        properties[key] = value;
                    } while (xNav.MoveToNextAttribute());
                    Style style = new Style(name, properties);
                    Styles.Add(style.Name, style);
                }
            }
        }
    }
}
